package com.jasonzqshen.ifm.collections.treeCollection;

import java.util.Collection;
import java.util.Hashtable;

import org.w3c.dom.*;

import com.jasonzqshen.ifm.collections.treeCollection.factories.*;
import com.jasonzqshen.ifm.utils.Identifier;

public class TreeRoot extends TreeObject implements NonLeaf {
    protected Hashtable<Identifier, NonRoot> children;

    /**
     * Construct Tree Root
     * 
     * @param id
     */
    public TreeRoot(Identifier id) {
        super(id);

        this.children = new Hashtable<Identifier, NonRoot>();
    }

    /**
     * Get children.
     * 
     * @return
     */
    public final Collection<NonRoot> getChildren() {
        return children.values();
    }

    /**
     * Get children based on the id.
     * 
     * @param id
     * @return
     */
    public final NonRoot getChild(Identifier id) {
        return this.children.get(id);
    }

    /**
     * Add child into tree root. And set child's parent as this.
     * 
     * @param child
     */
    public void addChild(NonRoot child) {
        this.children.put(child.getIdentifier(), child);
        child.setParent(this);
    }

    /**
     * remove child from root.
     */
    @Override
    public boolean removeChild(NonRoot child) {

        return false;
    }

    /**
     * check tree contains the child just check the identifier.
     */
    @Override
    public final boolean containChild(NonRoot child) {
        return this.children.containsKey(child.getIdentifier());
    }

    /**
     * Parse tree root to XML Element
     * 
     * @throws TreeCollectionException
     */
    @Override
    public Element toXElem() throws TreeCollectionException {
        Element xelem = super.toXElem();
        for (NonRoot child : this.children.values()) {
            if (!(child instanceof TreeObject)) {
                continue;
            }
            TreeObject obj = (TreeObject) child;
            xelem.appendChild(obj.toXElem());
        }

        return xelem;
    }

    /**
     * Parse XML to tree leaf.
     * 
     * @param xelem
     * @param factory
     * @throws TreeCollectionException
     */
    public static void xmlParser(Element xelem, TreeFactory factory,
            TreeRoot root) throws TreeCollectionException {
        // construct tree root children
        NodeList nodeList = xelem.getChildNodes();
        int len = nodeList.getLength();
        for (int i = 0; i < len; ++i) {
            Node child = nodeList.item(i);
            if (!(child instanceof Element)) {
                continue;
            }

            Element tmpXElem = (Element) child;
            TreeObject tmpObj = TreeObject.xmlParser(tmpXElem, factory);

            if (tmpObj instanceof TreeNode) {
                TreeNode node = (TreeNode) tmpObj;
                TreeNode.xmlParser(tmpXElem, factory, node);
            } else if (tmpObj instanceof TreeLeaf) {
                TreeLeaf leaf = (TreeLeaf) tmpObj;
                TreeLeaf.xmlParser(tmpXElem, factory, leaf);
            }

            root.addChild((NonRoot) tmpObj);
        }
    }

    @Override
    public boolean equals(Object obj) {
        boolean flag = super.equals(obj);
        if (flag == false) {
            return false;
        }

        if (!(obj instanceof TreeRoot)) {
            return false;
        }

        TreeRoot root = (TreeRoot) obj;
        // check child
        return this.children.equals(root.children);
    }
}
